package services

import (
	"errors"
	"fmt"
	"github.com/jassue/jassue-gin/app/common/request"
	"github.com/jassue/jassue-gin/app/models"
	"github.com/jassue/jassue-gin/global"
	"github.com/jassue/jassue-gin/utils"
	"gorm.io/gorm"
)

type menuService struct {
}

var MenuService = new(menuService)

// 添加菜单
func (menuService *menuService) AddMenu(params request.AddMenu) (err error) {

	var result = global.App.DB.Where("name = ?", params.Name).Select("id").First(&models.Permissions{})
	if result.RowsAffected != 0 {
		err = errors.New("菜单名已存在")
		return err
	}
	menu := models.Permissions{Pid: params.Pid, Name: params.Name, Guard_name: params.Guard_name, Url: params.Url, Title: params.Title,
		Menu_type: params.Menu_type, Sort: params.Sort, Level: params.Level,
	}
	err = global.App.DB.Create(&menu).Error
	return
}

// 编辑菜单
func (menuService *menuService) EditMenu(params request.EditMenu) (err error) {

	var result = global.App.DB.Where("id<> ? and name = ?", params.Id.Id, params.Name).Select("id").First(&models.Permissions{})
	if result.RowsAffected != 0 {
		err = errors.New("菜单名已存在")
		return err
	}
	menu := models.Permissions{Pid: params.Pid, Name: params.Name, Guard_name: params.Guard_name, Url: params.Url, Title: params.Title,
		Menu_type: params.Menu_type, Sort: params.Sort, Level: params.Level,
	}

	//编辑数据
	global.App.DB.Model(&menu).Where("id = ?", params.Id.Id).Updates(&menu)

	return
}

// 菜单排序
func (menuService *menuService) SetMenuSort(params request.SetMenuSort) (err error) {
	menu := models.Permissions{Sort: params.Sort}
	//编辑数据
	global.App.DB.Model(&menu).Where("id = ?", params.Id.Id).Updates(&menu)
	return
}

// 删除菜单
func (menuService *menuService) Del(params request.Del) (err error) {
	return global.App.DB.Transaction(func(db *gorm.DB) error {
		//select
		var result = db.Where("pid= ? ", params.Id.Id).Select("id").First(&models.Permissions{})
		if result.RowsAffected != 0 {
			err = errors.New("该菜单有子菜单，请先删除子菜单")
			return err
		}

		TxErrc := db.Delete(&[]models.Permissions{}, "id = ?", params.Id.Id).Error
		if TxErrc != nil {
			return TxErrc
		}

		//同时删除 role_has_permissions  casbin_rule 2张表数据

		TxErrc2 := db.Delete(&[]models.RoleHasPermissions{}, "permission_id = ?", params.Id.Id).Error
		if TxErrc2 != nil {
			return TxErrc2
		}

		TxErrc3 := db.Delete(&[]models.Casbin_rule{}, "v1 = ?", utils.Int2string(params.Id.Id)).Error
		if TxErrc3 != nil {
			return TxErrc3
		}

		return nil
	})
}

// 后台菜单列表 menu_type=1 全部 菜单和按钮  menu_type=2 只有菜单
func (menuService *menuService) GetMenuList(params request.GetMenuList) (err error, res []models.Node) {

	var mt []int
	if params.Menu_type == 1 {
		mt = []int{0, 1}
	} else {
		mt = []int{1}
	}
	var result []models.Permissions
	var list []models.Node

	global.App.DB.Where("menu_type in ?", mt).Order("sort asc").Find(&result)

	for _, v := range result {
		list = append(list, models.Node{
			ID: v.ID, Pid: v.Pid, Name: v.Name, Title: v.Title, Sort: v.Sort, Menu_type: v.Menu_type, Level: v.Level, Children: nil,
		})
	}

	//变成树形结构
	res = array2tree(list, 0)

	//树形结构转平铺 并保持上下级顺序
	arr := tree2array(res)

	return nil, arr
}

// 平铺转树形结构
func array2tree(list []models.Node, parentId uint) []models.Node {
	res := make([]models.Node, 0)
	for _, v := range list {
		if v.Pid == parentId {
			v.Children = array2tree(list, v.ID.ID)
			res = append(res, v)
		}
	}
	return res
}

// 树形结构转平铺 并保持上下级顺序
func tree2array(tree []models.Node) []models.Node {
	arr3 := make([]models.Node, 0)
	//fmt.Printf("tree  %+v\n", tree)
	for _, v := range tree {
		arr3 = append(arr3, models.Node{ID: v.ID, Pid: v.Pid, Name: v.Name, Title: v.Title,
			Sort: v.Sort, Menu_type: v.Menu_type, Level: v.Level, Children: nil})
		if len(v.Children) != 0 {
			//fmt.Printf("v.Children  %+v\n", v.Children)
			arr3 = append(arr3, tree2array(v.Children)...)
		}
	}

	return arr3
}

// 动态获取用户菜单
func (menuService *menuService) GetMenu(uid int) (err error, res []models.Node) {

	sql := "select p.* from user_roles left join  " +
		"roles r on user_roles.role_id = r.id " +
		"left join role_has_permissions rhp on r.id = rhp.role_id " +
		"left join permissions p on rhp.permission_id = p.id and p.menu_type=1 " +
		"where user_roles.model_id= ? group by p.id having p.id>0 ;"

	var result []models.Permissions

	global.App.DB.Raw(sql, uid).Scan(&result)

	var list []models.Node
	//
	for _, v := range result {
		list = append(list, models.Node{
			ID: v.ID, Pid: v.Pid, Name: v.Name, Title: v.Title, Sort: v.Sort, Menu_type: v.Menu_type, Level: v.Level, Children: nil,
		})
	}

	res = array2tree(list, 0)

	return nil, res
}

func (menuService *menuService) GetButtonPermissions(uid int) (err error, list []uint) {

	sql := "select p.id from user_roles left join  " +
		"roles r on user_roles.role_id = r.id " +
		"left join role_has_permissions rhp on r.id = rhp.role_id " +
		"left join permissions p on rhp.permission_id = p.id and p.menu_type=0 " +
		"where user_roles.model_id= ? group by p.id having p.id>0 ;"

	var result []*models.Button

	global.App.DB.Raw(sql, uid).Scan(&result)

	for _, v := range result {
		list = append(list, v.ID.ID)
	}

	return nil, list
}

// 获取菜单id
func (menuService *menuService) GetMenuId(name string) (stringId string) {
	var result *models.Button

	global.App.DB.Raw(" select id from permissions where name =?", name).Scan(&result)

	fmt.Printf("result2:%#v\n", result)

	if result == nil {
		stringId = ""
	} else {
		stringId = utils.Int2string(result.ID.ID)
		fmt.Printf("s2tringId:%s \n", stringId)
	}

	return stringId
}
